#ifndef __WAVE_IO_H__
#define __WAVE_IO_H__ 1

#include "sample_io.h"
#include "wave/riff_wave.h"
#include "wave/riff_wave_writer.h"

class CWaveIO : public ISampleIO
{
public:
	/**
	 * for read and write
	 */
	CWaveIO(EAction pAction,
			std::string pWavInputFile,
			std::string pWavOutputFile,
			double pDiscardTime);

	/**
	 * only for read
	 */
	CWaveIO(EAction pAction, std::string pWavInputFile, bool pReplayInput);

	/**
	 * only for write
	 */
	CWaveIO(EAction pAction,
			std::string pWavOutputFile,
			NAudioFormats::SStreamInfo pStreamInfo);

	virtual ~CWaveIO();

	/* START methods inherited by ISampleIO */
	virtual int init(CPropertiesReader *pConfig);
	virtual int destroy();

	virtual int read(void** pData, EAction& pAction, int pTimeout = 1000);
	/**
	 * @param pMaxRead max read in bytes
	 */
	virtual int read(void** pData, EAction& pAction, int pTimeout, int pMaxRead);
	virtual int write(void* pData, const EAction& pAction, int pLength);

	virtual NAudioFormats::SStreamInfo getStreamInfo();
	/* END methods inherited by ISampleIO */

private:
	static const std::string sIniSectionName;

	enum EInitError {
		INIT_NO_ERROR          = 0,

		// errors
		INIT_FAILURE           = 1,
		INIT_WAVE_INPUT_ERROR  = 2,
		INIT_WAVE_OUTPUT_ERROR = 3,
	};

	EInitError mError;
	EAction mAction;
	CRiffWave *mWavIn;
	CRiffWaveWriter *mWavOut;
	unsigned char *mReadByteBuffer;
	bool mReplayInput;
	int mDiscardByteCount;

	unsigned int mBytePerSample;
	NAudioFormats::SStreamInfo mStreamInfo;

	bool mReadInRealtime;

	CWaveIO(const CWaveIO& );
	CWaveIO& operator=(const CWaveIO& );

	bool openInputFile(std::string pMonoWavInputFile);
	NAudioFormats::ESamplesWidth getSampleWidth(unsigned int pBitsPerSample);
	unsigned int getBitsPerSample(NAudioFormats::ESamplesWidth pSampleWidth);
	NAudioFormats::ECodec getCodec(NWaveFormatTag::EFormatTag pWaveFormatTag);
	NWaveFormatTag::EFormatTag getWaveFormatTag(NAudioFormats::ECodec pCodec);
};

#endif /* __WAVE_IO_H__ */
